package com.mars.boss.manager.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.mars.boss.manager.constants.RedisKeyConst;
import com.mars.boss.manager.entity.Menu;
import com.mars.boss.manager.exception.MenuBizException;
import com.mars.boss.manager.mapper.MenuMapper;
import com.mars.boss.manager.service.MenuService;
import com.mars.common.component.redis.JedisClient;
import com.mars.common.exception.BizException;
import com.mars.common.service.support.BaseService;
import com.mars.common.utils.Pinyin4jHelper;
import com.mars.common.utils.RandomUitl;

@Service
public class MenuServiceImpl extends BaseService<Menu, Long> implements MenuService {
	
	@Autowired
	private MenuMapper mapper ;

	@Autowired
	private JedisClient jedisClient;
	
	@Override
	public int insert(Menu entity) throws MenuBizException {
		if(null == entity.getName()) {
			throw MenuBizException.MENU_NAME_NOT_NULL ;
		}
		if(null == entity.getCode() || "".equals(entity.getCode())) {
			entity.setCode("C_"+Pinyin4jHelper.getPinYinHeadUperChar(entity.getName())+"_"+RandomUitl.generateInteger(3));
		}
		int insert = super.insert(entity) ;
		if(null != entity.getChoose() && entity.getChoose() == 1) {
			updateChooseDefault(entity.getId()) ;
		}
		clearCache() ;
		return insert;
	}
	
	@Override
	public int deleteByIds(String ids) throws BizException {
		deletes(Long.parseLong(ids));
		clearCache() ;
		return 0;
	}
	
	private void deletes(Long id) {
		List<Menu> children = this.mapper.getMenuByParentId(id) ;
		if(null != children) {
			for (Menu menu : children) {
				deletes(menu.getId());
			}
		}
		super.delete(id) ;
	}
	
	@Override
	public int update(Menu entity) throws MenuBizException {
		if(entity.getId() == entity.getParentId()) {
			throw MenuBizException.NOT_RELATED_SELF ;
		}
		int update = super.update(entity);
		
		if(null != entity.getChoose() && entity.getChoose() == 1) {
			updateChooseDefault(entity.getId()) ;
		}
		clearCache() ;
		return update;
	}
	
	@Override
	public List<Menu> getMenuCategory() throws MenuBizException {
		String menus = jedisClient.get(RedisKeyConst.MENU_CATEGORY) ;
		if(null != menus) {
			return JSON.parseArray(menus, Menu.class) ;
		} else {
			List<Menu> list = this.mapper.getMenuCategory() ;
			this.jedisClient.set(RedisKeyConst.MENU_CATEGORY, JSON.toJSONString(list));
			return list ;
		}
	}

	@Override
	public List<Menu> getMenuByParentId(Long id) {
		String menus = jedisClient.getHash(RedisKeyConst.MENU_CATEGORY_TREE, RedisKeyConst.MENU_CATEGORY_TREE + ":" + id) ;
		if(null != menus) {
			return JSON.parseArray(menus, Menu.class) ;
		} else {
			List<Menu> list = new ArrayList<Menu>() ;
			List<Menu> menuByCategory = this.mapper.getMenuByParentId(id) ;
			for (Menu menu : menuByCategory) {
				if(menu.getLeaf() == 1) {menu.setState("open");}
				list.add(recursiveMenu(menu)) ;
			}
			this.jedisClient.setHash(RedisKeyConst.MENU_CATEGORY_TREE, RedisKeyConst.MENU_CATEGORY_TREE + ":" + id, JSON.toJSONString(list));
			return list ;
		}
	}
	
	@Override
	public List<Menu> getAllMenus() {
		String menus = jedisClient.get(RedisKeyConst.MENU_ALL) ;
		if(null != menus) {
			return JSON.parseArray(menus, Menu.class) ;
		} else {
			List<Menu> list = new ArrayList<Menu>() ;
			List<Menu> menuCategory = this.getMenuCategory() ;
			for (Menu menu : menuCategory) {
				menu.setState("open");
				list.add(recursiveMenu(menu)) ;
			}
			this.jedisClient.set(RedisKeyConst.MENU_ALL, JSON.toJSONString(list));
			return list ;
		}
	}
	
	public Menu recursiveMenu(Menu menu) {
		List<Menu> childs = this.mapper.getMenuByParentId(menu.getId()) ;
		if(null != childs && childs.size() > 0) {
			List<Menu> children = new ArrayList<Menu>() ;
			for (Menu m : childs) {
				if(m.getLeaf() == 1) {m.setState("open");}
				children.add(recursiveMenu(m)) ;
			}
			menu.setChildren(children);
		} else {
			menu.setState("open");
		}
		return menu ;
	}

	@Override
	public Menu getMenuByURL(String url) throws MenuBizException {
		String menuStr = jedisClient.getHash(RedisKeyConst.MENU_BY_URL, url) ;
		if(null != menuStr) {
			return JSON.parseObject(menuStr, Menu.class) ;
		} else {
			this.jedisClient.del(RedisKeyConst.MENU_BY_URL);
			List<Menu> menuList = this.mapper.getMenusByURL() ;
			for (Menu menu : menuList) {
				jedisClient.setHash(RedisKeyConst.MENU_BY_URL, menu.getUrl(), JSON.toJSONString(menu));
			}
			String hashMenu = jedisClient.getHash(RedisKeyConst.MENU_BY_URL, url) ;
			return JSON.parseObject(hashMenu, Menu.class) ;
		}
	}

	@Override
	public int updateChooseDefault(Long id) {
		return this.mapper.updateChooseDefault(id);
	}
	
	/**
	 * 清除缓存
	 */
	public boolean clearCache() {
		this.jedisClient.del(RedisKeyConst.MENU_ALL);
		this.jedisClient.del(RedisKeyConst.MENU_BY_URL);
		this.jedisClient.del(RedisKeyConst.MENU_CATEGORY);
		this.jedisClient.del(RedisKeyConst.MENU_CATEGORY_TREE);
		return true ;
	}

	
}
